Release 10.1A: OpenEdge Application Server:
Developing AppServer Applications
Buffer currency and NO-LOCK
If you try to find a record with
NO-LOCKand that record is already located in a buffer, then depending on the exact nature of the request, OpenEdge may not reread the record from the database.The fact that OpenEdge does not always reread
NO-LOCKrecords may cause unexpected behavior in your distributed application. More specifically, although a record was updated within one session (client or AppServer), that update may not be seen within another session if that record was previously read withNO-LOCK. There are two scenarios where this may occur. These scenarios are called currency conflicts to denote the fact that they involve a buffer whose contents is not current:
- Client-server currency conflict
In this scenario, a client finds a record
NO-LOCK, and then sends a request to an AppServer to update the same record. When the request finishes, the client attempts to find the same record. Because OpenEdge may not reread the record, the client buffer might contain the copy of the record before the update occurred rather than the updated copy of the record.- Server-server currency conflict
In this scenario, a client sends a request to an AppServer whose operating mode is stateless. The AppServer agent who processes the request updates some record. The client then sends another request to the AppServer. This request happens to go to an AppServer agent that is different then the one that processed the first request. The AppServer agent attempts to find the same record that was updated using
NO-LOCK. If the record was already stored in a buffer due to some previous clients request executed at this AppServer agent, OpenEdge may not reread the record. When this occurs, the AppServer agent buffer will contain the copy of the record before the update occurred rather than the updated copy of the record.If resolving client-server or server-server currency conflicts is important to you, there are three general approaches that you can use:
Reading the current record
If you know exactly which buffer is out of date, use
FINDCURRENTorGETCURRENTwithNO-LOCK. TheCURRENTkeyword indicates to OpenEdge that the record must be reread.Releasing the record
Use the
RELEASEstatement on all buffers that may be out of date before the record is reread. TheRELEASEstatement will clear the records from all buffers to which it is applied. At that point, all records that OpenEdge reads will need to be read from the database because a buffer copy no longer exists.Setting the -rereadnolock parameter
The
-rereadnolockparameter indicates to OpenEdge that when an attempt is made to find a recordNO-LOCK, even if the record is already in a buffer, then the record should be reread from the database. Use it as a Progress 4GL client startup parameter to resolve client-server currency conflicts. Use it as an AppServer startup parameter via the Progress Explorer or by setting thesrvrStartupParamproperty in theubroker.propertiesfile for the appropriate AppServer to resolve server-server currency conflicts.Note there are several things to keep in mind when using the
-rereadnolockstartup parameter:
- The
-rereadnolockparameter has no affect on records that are being retrieved viaRECIDorROWID. In that case, OpenEdge will not reread the record. It will use the copy of the record already stored in the buffer. If the most current version of the record is needed, then use theRELEASEstatement on all buffers that contain a copy of the record before reading the record, or useFINDCURRENTorGETCURRENTstatement to reread the record.- The
-rereadnolockparameter has no affect on the behavior of the query cache used for aNO-LOCKquery as specified via theCACHEn phrase of theDEFINEQUERYstatement. If the record is in the cache, it will not be reread regardless of whether-rereadnolockis set. To force the record to always be reread setCACHE0. Note that setting the cache size to zero (0) may significantly degrade performance if the database is being accessed across a network. Only set the cache size to zero (0) when it is critical to retrieve the most current version of a record.- The
-rereadnolockparameter has no affect on the behavior of the prefetch cache that is used by default when retrieving recordsNO-LOCKacross the network. By default, when executing aCAN-FINDfunction, or theFIND,FOR, orOPEN QUERYstatements on a database which is being accessed across a network, OpenEdge fetches several records at a time, and stores those records within a prefetch cache. OpenEdge will only sends a request to the database server to fetch more records if the requested record is not contained within the current prefetch cache. If the record is in this cache, a new copy of that record will not be read even if-rereadnolockis set. To eliminate this cache so that the most current version of the record is always read use theNO-PREFETCHkeyword in the appropriate statements. Note that using theNO-PREFETCHkeyword may significantly degrade performance. Only setNO-PREFETCHwhen it is critical to retrieve the most current version of a record.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |